<?php

namespace App\Http\Controllers\Operation\Model;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Validation\Rule;
use App\Services\ModelCategoryService;
use App\ModelCategory;

class ModelCategoryController extends Controller
{
    private $modelCategoryService = null;

    public function __construct(ModelCategoryService $modelCategoryService)
    {
        $this->modelCategoryService = $modelCategoryService;
    }

    public function index()
    {
        return view('operation.model.category.category');
    }

    public function getInitCategoryTrees()
    {
        return $this->modelCategoryService->getCascadeCategories();
    }

    public function query(Request $request)
    {
        return $this->modelCategoryService
            ->getCategories($request->all());
    }

    public function createCategory($parentId)
    {
        if (!empty($parentId)) {
            $parent = ModelCategory::findOrFail($parentId);
        } else {
            $parent = null;
        }
        return view('operation.model.category.create', [
            'parentId' => $parentId,
            'possiableParents' => $this->modelCategoryService->getPossiableParentCategories($parent),
        ]);
    }

    public function saveNewCategory(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveNewCategory($input);

        ModelCategory::create([
            'name' => $input['name'],
            'parent_id' => !empty($input['parent_id'])?$input['parent_id']:null,
            'sort_order' => $input['sort_order'],
        ]);

        return response()->json([
            'Success' => true,
            'Message' => '新增分类成功',
        ]);
    }

    public function editCategory($categoryId)
    {
        $category = ModelCategory::findOrFail($categoryId);
        if (isset($category->parent_id)) {
            $parentId = $category->parent_id;
        } else {
            $parentId = 0;
        }

        $possiableParents = $this->modelCategoryService->getPossiableParentCategoriesExceptSelf($categoryId);

        return view('operation.model.category.create', [
            'parentId' => $parentId,
            'possiableParents' => $possiableParents,
            'category' => $category
        ]);
    }

    public function saveUpdateCategory(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveUpdateCategory($input);

        $category = ModelCategory::findOrFail($input['id']);
        $category->update([
            'id' => $input['id'],
            'name' => $input['name'],
            'parent_id' => !empty($input['parent_id'])?$input['parent_id']:null,
            'sort_order' => $input['sort_order']
        ]);

        return response()->json([
            'Success' => true,
            'Message' => '修改分类成功',
        ]);
    }

    public function deleteCategory(Request $request)
    {
        $input = $request->all();

        $this->validateWhenDeleteCategory($input);

        $category = ModelCategory::findOrFail($input['id']);
        $category->delete();

        return response()->json([
            'Success' => true,
            'Message' => '删除分类成功',
        ]);
    }

    private function getPossiableParentIds()
    {
        $categoryIds = ModelCategory::all()->pluck('id')->toArray();
        array_push($categoryIds, 0);
        return $categoryIds;
    }

    private function validateWhenSaveNewCategory(Array $input)
    {
        return Validator::make($input, [
            'name' => 'required|max:50|unique:model_categories,name',
            'parent_id' => [
                Rule::in($this->getPossiableParentIds())
            ],
            'sort_order' => 'required|numeric'
        ], [
            'name.required' => '分类名称不可为空',
            'name.max' => '分类名称长度不可超过:max',
            'name.unique' => '分类名称不可重复',
            'parent_id.in' => '传入的父级id不合法',
            'sort_order.required' => '必须传入同级排序号',
            'sort_order.numeric' => '同级排序号必须为数字'
        ])->validate();
    }

    private function getPossiableCategoryIdsWhenUpdate($categoryId)
    {
        $possiableCategoryIds = array_values($this->modelCategoryService->getPossiableParentCategoriesExceptSelf($categoryId)
            ->pluck('id')->toArray());

        array_push($possiableCategoryIds, 0);

        return $possiableCategoryIds;
    }

    private function validateWhenSaveUpdateCategory(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('model_categories')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'parent_id' => [
                Rule::in($this->getPossiableCategoryIdsWhenUpdate($input['id']))
            ],
            'sort_order' => 'required|numeric'
        ], [
            'name.required' => '分类名称不可为空',
            'name.max' => '分类名称长度不可超过:max',
            'name.unique' => '分类名称不可重复',
            'parent_id.in' => '传入的父级id不合法',
            'sort_order.required' => '必须传入同级排序号',
            'sort_order.numeric' => '同级排序号必须为数字'
        ])->validate();
    }

    private function validateWhenDeleteCategory(Array $input)
    {
        return Validator::make($input, [
                'id' => 'required|exists:model_categories,id'
            ], [
                'id.required' => '必须传入模型分类ID',
                'id.exists' => '该模型分类ID参数有误，不存在'
            ])->after(function ($validator) use($input) {
                if ($this->modelCategoryService->hasChildren($input['id'])) {
                    $validator->errors()->add('id', '该分类存在子分类，不可删除');
                }
                if ($this->modelCategoryService->hasConstrait($input['id'])) {
                    $validator->errors()->add('id', '该分类存在其它关联，不可删除');
                }
            })->validate();
    }
}
